import { mapState } from 'pinia';
import Print from '@/views/modules/form/js/Print';
import rxAjax from "@/assets/js/ajax.js";
import {Util} from '@lowcode/jpaas-base-lib';
import FormFunctions from "@/views/modules/form/js/FormFunctions";
import FormSolutionApi from "@/common/api/form/formSolution";
import DialogBox from "@/assets/js/dialogBox.js";
import FlowFunctions from "./FlowFunctions.js";
import router from "@/router";
import NodesExecutors from "@/views/modules/bpm/components/NodesExecutors.vue";
import userUser from "@/stores/userUser";
import PdfFunction from "@/views/modules/form/js/PdfFunction";

export default {
    mixins:[Print,PdfFunction,FlowFunctions],
    computed:{
        ...mapState(userUser, ['user']),
        parentVm(){
            let vm=this;
            while (vm && !vm.rootVm){
                vm=vm.$parent;
            }
            return vm;
        },
        rxForms(){
            return this.parentVm.$refs.rxForms;
        },
        customForm(){
            return this.parentVm.$refs.customForm;
        },
        outSideUrlForm(){
            return this.parentVm.$refs.outSideUrlForm;
        }
    },
    methods:{
        ...FormFunctions,
        //获取渲染表单对象
        getFormVm(){
            return this.rxForms.getCurrentForm().$refs.XForm;
        },
        getFormData(){
            let formType=this.parentVm.processConfig.formType;
            let formData={};
            if(formType=="online") {
                if(this.rxForms){
                    formData=this.rxForms.getData();
                }
            }
            return formData;
        },

        getData(){
            var defId=this.parentVm.localDefId;
            var data={defId:defId};
            var formType=this.parentVm.processConfig.formType;
            var hasPk=this.parentVm.processConfig.hasPk;
            var formData={};
            if(formType=="online"){
                if(this.rxForms){
                    formData=this.rxForms.getData();
                }
                data.systemHand=true;
                data.hasPk=hasPk;
            }
            else if(formType=="outsideUrl"){
                formData=this.outSideUrlForm.getData();
                data.systemHand=false;
            }
            else if(formType=="custom"){
                formData=this.customForm.getData();
                data.systemHand=false;
            }
            var formJson=JSON.stringify(formData);
            data.formJson=formJson;

            let isCopy=this.parentVm.isCopy;
            if(this.parentVm.instId && !isCopy){
                data.instId=this.parentVm.instId;
            }
            data.attachment=JSON.stringify( this.parentVm.attachments);
            data.relateProcess=JSON.stringify(this.parentVm.relateProcess);
            //幂等号
            let idempotenceid=this.parentVm.idempotenceid;
            if(idempotenceid){
                data.idempotenceid=idempotenceid;
            }
            return data;
        },
        /**
         * 执行表单方法。
         * @param btn
         */
        handFormMethod(btn){
            let rxForms=this.rxForms;
            let formRef;
            let method="";
            if(btn.method.indexOf(".")==-1){
                formRef=rxForms.getFormRef();
                method = btn.method;
            }
            else{
                let aryTmp=btn.method.split(".");
                let alias=aryTmp[0];
                method= aryTmp[1];
                formRef=rxForms.getFormRef(rxForms.getFormKey(alias));
            }
            if(!formRef){
                this.$message.warn(this.$ti18("FormBase.noFindForm","没有找到表单!"));
                return;
            }
            let formVm = formRef.$refs.XForm;
            if (formVm && formVm[method]) {
                formVm[method](btn);
            }
        },

        /**
         * 处理按钮是否显示
         * @param btn
         */
        changeBtnHandle(bpmActionType,processConfig,buttons,formData){
            let newBtns = [];
            if(!bpmActionType){
                return buttons;
            }
            if(!buttons || buttons.length==0){
                return newBtns;
            }
            for(let btn of buttons){
                let isShow = this.canShowBtn(bpmActionType,processConfig,btn,formData);
                if(isShow){
                    newBtns.push(btn);
                }
            }
            return newBtns;
        },
        canShowBtn(bpmActionType,processConfig,btn,formData){
            if(!btn.config || !btn.config.showScript){
                return true;
            }

            //当前登陆人
            //上下文
            let context ={
                instId:""
            };
            context = { ...context,...this.user };
            if(bpmActionType === "bpmTaskStart"){
                //流程实例ID
                context.instId =processConfig.bpmInst.instId;
                //流程状态
                context.instStatus =processConfig.bpmInst.status;
                //流程节点数据
                context.bpmNodeId =processConfig.taskConfig.key;
                context.bpmNodeCode =processConfig.taskConfig.alias;
                context.bpmNodeName =processConfig.taskConfig.name;
            }
            //表单数据
            let formJson=this.rxForms.getData();
            if(formData && Array.isArray(formData) && formData.length){
                let obj = {}
                for (let item of formData){
                    if(item && item.alias){
                        obj[item.alias] = item.data ;
                    }
                }
                formJson = obj;
            }
            try {
                let func=new Function("data","context",btn.config.showScript);
                let isShow =func.bind(this)(formJson,context);
                return isShow;
            }catch (e){
                console.log("是否显示按钮计算出错。默认不显示，错误信息：  "+e);
            }

            return false;
        },

        /**
         * 处理自定义方法。
         * @param btn
         */
        handCustom(btn){
            let rxAjax = this.rxAjax;
            let formJson=this.rxForms.getData();
            let config=btn.config;
            let func=new Function("rxAjax","formJson",config.action);
            func.bind(this)(rxAjax,formJson);
        },
        /**
         * 处理pdf打印方法。
         * @param btn
         */
        handPdfPrint(btn){
            let button = Util.deepClone(btn);
            let pkId = button.config.pkId;
            let boAlias = button.config.boAlias;
            button.config={
                defId:pkId,
                boAlias:boAlias,
            }
            this.pdfPrint(button);
        },
        /**
         * 执行按钮。
         * @param btn
         */
        handMethod(btn) {
            console.log(btn.method)
            let rxForms=this.parentVm.$refs.rxForms;
            //表单方法
            if(btn.type=="formMethod" && rxForms){
                //执行表单方法。
                this.handFormMethod(btn);
                return;
            }
            //pdf打印
            if(btn.type=="pdfPrint"){
                //执行pdf打印方法。
                this.handPdfPrint(btn);
                return;
            }
            //自定义方法
            if(btn.type=="custom"){
                this.handCustom(btn);
                return;
            }
            //调用预定义方法。
            this[btn.method](btn);
        },
        /**
         * 打开列表
         * @param btn
         */
        openBpmListDialog(btn){
            if (!btn.config){
                this.$message.warning(this.$ti18('msa.noList',"未配置列表","bpmTask"));
                return;
            }
            if (!btn.config.listConfig){
                this.$message.warning(this.$ti18('msa.noList',"未配置列表","bpmTask"));
                return;
            }
            var config=JSON.parse(btn.config.listConfig)
            var listConf = {
                curVm:this,
                max:config.isMax == "YES" ? true : false,
                shade:config.model,
            }
            if(config.isMax == "NO"){
                listConf["widthHeight"] = [config.width + 'px', config.height + 'px']
            }
            var fieldALlMap=JSON.parse(config.fieldMap);
            //筛选出使用表单字段映射的参数
            // 获取表单数据
            var formData=this.rxForms.getData();
            var allData={}
            for (let data in formData){
                Object.assign(allData,formData[data])
            }
            //var fieldMap=fieldALlMap.filter(item=>item.valueType=="field")
            var queryParams=[]
            var typeJson = {string: "S", int: "I", date: "D", float: "F"};
            if (fieldALlMap.length>0 ){
                for (let param of fieldALlMap){
                    let valType=param.valueType
                    var tablePre = param.tablePre ? param.tablePre + "." : "";
                    var type = typeJson[param.dataType] ? typeJson[param.dataType] : "S";
                    var queryString = "Q_" + tablePre + param.destField + "_" + type + "_" + param.fieldOp;
                    var tmp = ""
                    if (valType == "curUserId") {
                        tmp=queryString + "=" + this.user.userId;
                    } else if (valType == "curDeptId") {
                        tmp=queryString + "=" + this.user.deptId;
                    }else if (valType=="curName"){
                        tmp=queryString + "=" + this.user.fullName;
                    }else if (valType=="curTenantId"){
                        tmp=queryString + "=" + this.user.tenantId;
                    }else if (valType=="curUserAccount"){
                        tmp=queryString + "=" + this.user.account;
                    } else if (valType == "curdeptName") {
                        tmp=queryString + "=" + this.user.deptName;
                    } else if (valType == "curCompanyId") {
                        tmp=queryString + "=" + this.user.companyId;
                    } else if (valType == "field"){
                        let srcField=param.srcField.toLowerCase();
                        if(!srcField){
                            continue;
                        }
                        if (!allData[srcField]){
                            continue;
                        }
                        tmp=queryString + "=" + allData[srcField];
                    }

                    queryParams.push(tmp);
                }
            }

            DialogBox.dialog({key:config.alias,params:queryParams.join("&")},{...listConf},function (action,data) {});

        },
        /**
         * 打开表单。
         * @param btn
         */
        openSolutionForm(btn) {
            let self_ = this;
            let formJson = {};
            let config=btn.config;
            let rxForms;
            if(this.rxForms){
                rxForms = this.rxForms;
            }
            let formVm
            if(!config.mappingAlias){
                formVm= rxForms.getFormRef().$refs.XForm;
            }else {
                let formKey = "rxForm_" + config.mappingAlias;
                formVm =  rxForms.$refs[formKey][0]
            }
            formJson[formVm.alias] = rxForms.getData();
            let data=formJson[formVm.alias];
            let dataDetail = data[formVm.alias];
            let initData=this.getInitData(config,dataDetail,formVm);
            DialogBox.showForm({
                title: config.formName,
                curVm: self_,
                data: {
                    alias: config.formAlias, setInitData: function (data) {
                        return Object.assign(data, initData);
                    },
                    closeOnSave:true
                },
                max: true
            }, function (action,data) {
                if(formVm[config.callback]){
                    formVm[config.callback](action,data);
                }
            });
        },
        //获取打开表单的初始化数据
        getInitData(config,data,formVm){
            let formData={};
            if(!config.formConfig){
                return formData;
            }
            //根据配置 构建映射数据
            let formConfig=JSON.parse(config.formConfig);
            //遍历表配置
            for (let i = 0; i < formConfig.length; i++) {
                let obj=formConfig[i];
                if(!obj.fieldConfig || obj.fieldConfig.length==0){
                    continue;
                }
                //目标表类型
                let targetType= obj.targetType;
                //遍历字段配置
                for (let j = 0; j < obj.fieldConfig.length; j++) {
                    let fieldConfig=obj.fieldConfig[j];
                    let fieldCurType=fieldConfig.curType;
                    let targetField =fieldConfig.targetField;
                    let curTable = "sub__"+fieldConfig.curTable;
                    let curField = fieldConfig.curField;
                    let bindType = fieldConfig.bindType || "field";
                    let targetTable= "sub__"+obj.targetTable;
                    let targetTableName = obj.targetTable;
                    //映射到主表
                    if(targetType=="main"){
                        //当前主表
                        if(fieldCurType=="main"){
                            let val=this.getBindValue(data,curField,bindType,formVm);
                            formData[targetField]=val;
                        }else  if(fieldCurType=="onetoone"){ //当前一对一子表
                            let val=this.getBindValue(data[curTable],curField,bindType,formVm);
                            formData[targetField]=val;
                        }

                    }else if(obj.targetType=="onetoone"){//映射到一对一子表
                        //一对一子表无数据时默认{}
                        formData[targetTable] = formData[targetTable] || {};
                        //当前主表
                        if(fieldConfig.curType=="main"){
                            let val=this.getBindValue(data,curField,bindType,formVm);
                            formData[targetTable][targetField]=val;
                        }else{ //当前一对一子表
                            let val=this.getBindValue(data[curTable],curField,bindType,formVm);
                            formData[targetTable][targetField]=val;
                        }
                    }else if(obj.targetType=="onetomany") {//映射到一对多子表
                        formData[targetTable] = formData[targetTable] || [];
                        formData.initData = formData.initData || {};
                        //子表初始化数据
                        formData.initData[targetTableName]=formData.initData[obj.targetTable] || {};
                        //当前主表
                        if(fieldConfig.curType=="main"){
                            formData.initData[targetTableName][targetField]=data[curField];
                            let tableData=formData[targetTable];
                            if(tableData && tableData.length>0){
                                for (let k = 0; k < tableData.length; k++) {
                                    let val=this.getBindValue(data,curField,bindType,formVm);
                                    tableData[k][targetField]=val;
                                }
                            }
                        }else  if(fieldConfig.curType=="onetoone"){ //当前一对一子表
                            formData.initData[targetTableName][targetField]=data[curTable][curField];
                            let tableData=formData[targetTable];
                            if(tableData && tableData.length>0){
                                for (let k = 0; k < tableData.length; k++) {
                                    let val=this.getBindValue(data[curTable],curField,bindType,formVm);
                                    tableData[k][targetField]=val;
                                }
                            }
                        }else {//当前一对多子表
                            if(!data[curTable]){
                                continue;
                            }
                            let curTableData =data[curTable];
                            for (let k = 0; k < curTableData.length; k++) {
                                let row=curTableData[k];
                                let val=this.getBindValue(row,curField,bindType,formVm);
                                //一对多子表单行无数据时默认{}
                                if(!formData[targetTable][k]){
                                    let subRow=JSON.parse(JSON.stringify(formData.initData[targetTableName]));
                                    subRow[targetField]= val;
                                    formData[targetTable][k]=subRow;
                                }else {
                                    formData[targetTable][k][targetField]=val;
                                }
                            }
                        }
                    }
                }
            }

            return formData;
        },
        /**
         * 获取绑定值
         * @param (Object) data 当前表单数据
         * @param (String) curField 当前字段
         * @param (String) bindType 绑定类型
         * @param (Object) formVm 表单vm
         * @returns (Object) 绑定的数据.
         */
        getBindValue(data,curField,bindType,formVm){
            let type = bindType || "field";
            if(type=="field"){
                return data[curField];
            }
            if(type=="fixed"){
                return curField;
            }
            if(type=="script"){
                if(!curField){
                    return "";
                }
                if(!formVm[curField]){
                    return "";
                }
                return formVm[curField](data);
            }
        },


        /**
         * 打开自定义表单。
         * @param btn
         */
        openCustomForm(btn) {
            let self_ = this;
            let config=btn.config;
            let rxForms=this.parentVm.$refs.rxForms;
            let formJson = rxForms.getData();
            FormSolutionApi.getValueByCustomFormConfig({
                formJson: formJson,
                formConfig: config.formConfig || []
            }).then(res => {
                DialogBox.showForm({
                    title: config.formName,
                    curVm: self_,
                    data: {
                        alias: config.formAlias, setInitData: function (data) {
                            return Object.assign(data, res);
                        },
                        closeOnSave:true
                    },
                    max: true
                }, function (action,data) {
                    if(config.script){
                        let rxAjax = self_.rxAjax;
                        let formJson=self_.rxForms.getData();
                        let func=new Function("rxAjax","formJson","action","data", config.script);
                        func.bind(self_)(rxAjax,formJson,action,data);
                    }
                });
            })
        },



        goBack(){
            router.back()
        },
        //特送按钮
        specialDelivery(btn){
            let formJson =this.getFormJson();
            Util.open({
                component:NodesExecutors,
                curVm:this,
                widthHeight:['800px','550px'],
                title: this.$ti18('taskExecutors.exePath',"特送","bpmTask"),
                data:{
                    formData:JSON.parse(formJson),
                    bpmTask:this.bpmTaskDetail.bpmTask,
                    processConfig:this.bpmTaskDetail.processConfig,
                    taskConfig:this.bpmTaskDetail.taskConfig
                }
            },function (action,data){
                if(action!='ok'){
                    return;
                }
                var reg = /(taskId=[^&]*)(&{0,1})/m;
                let href=location.href.replace(reg,function (){
                    return "";
                });
                if(href.indexOf("?")==-1){
                    href+="?time=" + new Date().getTime();
                }
                else {
                    href+="&time=" + new Date().getTime();
                }

                location.href=href;
            });
        }
    }
}
